package main;

import java.io.Serializable;

import parserUML.AttributeObject;
import parserUML.ClassObject;
import parserUML.MethodObject;
import parserUML.ParamObject;

import com.trolltech.qt.core.QPoint;
import com.trolltech.qt.core.QRectF;
import com.trolltech.qt.core.Qt;
import com.trolltech.qt.gui.QFont;
import com.trolltech.qt.gui.QFontMetrics;
import com.trolltech.qt.gui.QGraphicsItem;
import com.trolltech.qt.gui.QGraphicsItemInterface;
import com.trolltech.qt.gui.QGraphicsScene;
import com.trolltech.qt.gui.QGraphicsSceneMouseEvent;
import com.trolltech.qt.gui.QKeyEvent;
import com.trolltech.qt.gui.QPainter;
import com.trolltech.qt.gui.QStyleOptionGraphicsItem;
import com.trolltech.qt.gui.QWidget;

public class QGraphicsClass extends QGraphicsItem implements Serializable{
	
	private static final long serialVersionUID = 8835463902039178306L;
	private int width;
	private int height;
	private ClassObject data;

	public QGraphicsClass() {
		super();
	}

	public QGraphicsClass(QGraphicsItemInterface parent, QGraphicsScene scene) {
		super(parent, scene);
	}
	
	public QGraphicsClass(QGraphicsScene scene, ClassObject o){
		super (null,scene);
		data = o;
	}

	public QGraphicsClass(QGraphicsItemInterface parent) {
		super(parent);
	}

	public QGraphicsClass(QPrivateConstructor arg0) {
		super(arg0);
	}
	
	@Override
	public void mouseMoveEvent(QGraphicsSceneMouseEvent event){
		Actions.SceneRedef scene = (Actions.SceneRedef)this.scene();
		scene.recalcInheritance();
		super.mouseMoveEvent(event);
	}
	
	@Override
	public void keyPressEvent(QKeyEvent event) {
		if (event.key() == Qt.Key.Key_Delete.value()) {
			//this.dispose();
			this.hide();
		}
	}

	/*
	@Override
	public void mousePressEvent(QGraphicsSceneMouseEvent event) {
		if (event.button() == Qt.MouseButton.RightButton){
			System.out.println("Clic droit sur une classe");
			QMenu menu = new QMenu ();
			menu.addAction("Afficher", this, "affClic(boolean)");
			menu.exec(event.buttonDownScreenPos(Qt.MouseButton.RightButton));
		}
	}
*/
	@Override
	public QRectF boundingRect() {
		return new QRectF(0,0,width,height);
	}
	
	@Override
	public void paint(QPainter painter, QStyleOptionGraphicsItem option, QWidget widget) {
		
		//Set the font
		painter.setFont(new QFont("arial",10));
		
		// Get the font metrics of the painter to calc the size of strings
		QFontMetrics metrics = painter.fontMetrics();
		
		// Save the size of the larger string displayed
		if (data == null) return;
		if (!data.visible) return;
		
		String nom = data.getName();
		
		width = metrics.boundingRect(nom).width()+10;
		
		// Set the starting point of drawing 
		QPoint current = new QPoint(10,37);
		// Set the step used to draw text line by line
		QPoint pas = new QPoint(0,15);
		
		// Display the attributes of the class
		String ajout;
		for (AttributeObject a : data.attributes){
			ajout="";
			if (a.visible) {
				if(a.modifiers.contains("protected")){
					ajout+="# ";
				}
				else if(a.modifiers.contains("private")){
					ajout+="- ";
				}
				else {
					ajout+="+ ";
				}
				ajout += a.getType()+ " "+a.getName();
				painter.drawText(current, ajout);
				width = Math.max(width, metrics.boundingRect(ajout).width())+10;
				current.add(pas);
			}
		}
		
		//Save the ordinate of the line to draw after the attributes
		int yAttributes = current.y();
		current.add(pas);
	 	
		//Display methods and parameters
		String params;
		for (MethodObject m : data.methods){
			if (m.visible) {
				
				ajout="";
				
				if(m.modifiers.contains("protected")){
					ajout+="# ";
				}
				else if(m.modifiers.contains("private")){
					ajout+="- ";
				}
				else {
					ajout+="+ ";
				}
				
				params = "";
				for (ParamObject p : m.params){
					params += p.getType()+",";
				}
				if (!params.equals("")) params = params.substring(0, params.length()-1);
				ajout += m.getType()+ " " + m.getName() + "("+params+")";
				
				// update the size of the larger string displayed if needed
				width = Math.max(width, metrics.boundingRect(ajout).right())+10;
				
				painter.drawText(current, ajout);
				current.add(pas);
			}
		}

		//Display the name
		painter.drawText((width-metrics.width(data.getName()))/2, 15, data.getName());
		
		// Display the rect and lines of the object
		painter.drawRoundRect(0, 0, width, current.y());
		painter.drawLine(0, 20, width, 20);
		painter.drawLine(0,yAttributes,width,yAttributes);
		
		height = current.y();
	}
	
	public ClassObject getData(){
		return data;
	}
	
	public void setData(ClassObject c){
		data = c;
	}
	
	public void affClic(boolean item){
		this.update();
	}
}
